<?php

/**
 * Description of ViewXsl.
 * Similar to ViewPage, but instead of HTML, produces an XSL template to be applied to the XML data.
 * A 'page' is made up of 'panels', such as header, footer, left panel, right panel, and main content.
 * A 'panel' is made up of articles.
 * An 'article' may contain any of the following:
 * a heading, author, start date, expiry date, block of text,
 * array of media (e.g. links, images, videos, PDF files, etc) and a form.
 *
 * @author Ian Clarence <ian.clarence@gmail.com>
 */
abstract class ViewXsl extends ViewHtmlElement {

    /**
     * Namespace.
     */
    const XMLNS = 'http://www.w3.org/1999/XSL/Transform';

    /**
     * The constructor.
     *
     * @param array $fields
     */
    public function __construct(array $fields = array()) {

        $fields['tag'] = 'xsl:stylesheet';
        $fields['xmlns'] = self::XMLNS;

        parent::__construct($fields);

        $this->setAttribute('version', '1.0');
        $this->setAttribute('xmlns:xsl', $this->fields['xmlns']);
        $output = ViewHtmlElement::elementInit('xsl:output', NULL, 'method', 'html');
        $output->setAttribute('version', '4.0');
        $output->setAttribute('encoding', CHARSET);
        $this->addInnerHtml($output);
        $template = ViewHtmlElement::elementInit('xsl:template', NULL, 'match', '/');
        $html = ViewHtmlElement::elementInit('html');
        $html->addInnerHtml($this->getHead());
        switch (DEBUGGING_MODE) {
            case OFF:
                $html->addInnerHtml($this->getBody());
                break;
            case ON:
                $html->addInnerHtml($this->getDebugBody());
                break;
        }
        $template->addInnerHtml($html);
        $this->addInnerHtml($template);
    }
    
    /**
     * Getting the URL of this page.
     * 
     * @return string
     */
    protected function getPageUrl() {
        return $this->fields['page']['full_url'];
    }
    
    /**
     * Getting the URL of the resource.
     * 
     * @return string
     */
    protected function getResource() {
        $protocol = $this->fields['page']['is_secure'] ? 'https://' : 'http://';
        return $protocol . $this->fields['page']['resource'];        
    }

    /**
     * getting the page head.
     *
     * @return ViewHtmlElement
     */
    private function getHead() {
        $head = new ViewHead(array('title_text' => $this->fields['page']['title_text']));

        /**
         * JavaScript libraries.
         */
        $jsLibraries = array(
            'https://www.google.com/jsapi',
            'https://ajax.googleapis.com/ajax/libs/jquery/' . JQUERY_VERSION . '/jquery.min.js',
            'https://ajax.googleapis.com/ajax/libs/jqueryui/' . JQUERY_UI_VERSION . '/jquery-ui.min.js',
            ViewUtils::addUrlComponent($this->getResource(), JAVASCRIPT_FOLDER . '/' . JAVASCRIPT_FILENAME),
            ViewUtils::addUrlComponent($this->getPageUrl(), JAVASCRIPT_FILENAME)
        );
        foreach ($jsLibraries as $library) {
            $script = new ViewScript(array('src' => $library));
            $script->addInnerHtml(ViewHtmlElement::textInit(''));
            $head->addInnerHtml($script);
        }

        /**
         * CSS libraries.
         */
        $cssLibraries = array(
            ViewUtils::addUrlComponent($this->getResource(), CSS_FOLDER . '/' . CSS_FILENAME),
            ViewUtils::addUrlComponent($this->getPageUrl(), CSS_FILENAME)
        );
        foreach ($cssLibraries as $library) {
            $style = new ViewLink(array('href' => $library));
            $head->addInnerHtml($style);
        }

        return $head;

    }
    
    /**
     * Instance of a panel.
     * 
     * @param array $panel
     * @return mixed
     */
    protected function getPanelInstance($panel) {
        return NULL;
    }

    /**
     * Getting the page body for when in normal running mode.
     *
     * @return ViewHtmlElement
     */
    protected function getBody() {
        $container = ViewHtmlElement::elementInit('div', NULL, 'id', 'container');
        foreach ($this->fields['panels'] as $panel) {
            $viewPanel = $this->getPanelInstance($panel);
            $viewPanel->make();
            $container->addInnerHtml($viewPanel);
        }
        $body = $container->encapsulate('body');
        return $body;
    }

    /**
     * Getting the page body for when in debugging mode.
     *
     * @return ViewHtmlElement
     */
    private function getDebugBody() {

        $contents = ViewHtmlElement::elementInit('div', NULL, 'id', 'contents');
        $contents->addBr();
        $contents->addH2($this->fields['page']['description']);

        $headings = array(
            'page' => 'This Page',
            'languages' => 'Language Links',
            'domains' => 'Domain Links',
            'subdomains' => 'Subdomain Links',
            'parent' => 'Parent Page',
            'children' => 'Child Pages',
            'siblings' => 'Sibling Pages',
            'primaries' => 'Primary Pages',
            'descendants' => 'Descendant Pages',
            'ancestors' => 'Ancestor Pages',
            'panels' => 'Panels'
        );
        foreach ($this->fields as $fieldKey => $field) {
            if ($fieldKey == 'test' || $fieldKey == 'tag' || $fieldKey == 'attributes' || $fieldKey == 'doctype' || $fieldKey == 'xmlns') {

            }
            else if ($fieldKey == 'stats') {
                $contents->addH3('Stats');
                $contents->addP('Database calls: ' . $field['db']['count'] . '.');
                $contents->addP('Time for database calls: ' . $field['db']['totalTime'] . 's.');
                $contents->addP('Time to load page: ' . $field['page']['totalTime'] . 's.');
                $contents->addP('Remaining time: ' . ($field['page']['totalTime'] - $field['db']['totalTime']) . 's.');
            }
            else if ($fieldKey == 'page' || $fieldKey == 'parent') {
                $contents->addH3($headings[$fieldKey]);
                if (isset($field['full_url'])) {
                    $summary = ViewUtils::viewSummary($field['id'], $field['name'], $field['full_url']);
                }
                else {
                    $summary = ViewUtils::viewSummary($field['id'], $field['name']);
                }
                $contents->addInnerHtml($summary);
            }
            else {
                $contents->addH3($headings[$fieldKey]);
                if (count($field) > 0) {
                    $ul = ViewHtmlElement::elementInit('ul');
                    foreach ($field as $key => $value) {
                        if (isset($value['full_url'])) {
                            $summary = ViewUtils::viewSummary($value['id'], $value['name'], $value['full_url']);
                        }
                        else {
                            $summary = ViewUtils::viewSummary($value['id'], $value['name']);
                        }
                        $ul->addLi($summary);
                    }
                    $contents->addInnerHtml($ul);

                }
                else {
                    $contents->addP('There are no ' . strtolower($headings[$fieldKey]) . '.');
                }
            }
        }

        $contents->addH3('Language');
        if (isset($this->fields['page']['language'])) {
            $p = $this->fields['page']['language']['name'] . ' (' . $this->fields['page']['language']['code'] . ')';            
        }
        else {
            $p = 'Not a multilingual site.';
        }
        $contents->addP($p);

        $contents->addH3('Articles');

        foreach ($this->fields['panels'] as $panel) {
            $viewPanel = $this->getPanelInstance($panel);
            $contents->addInnerHtml($viewPanel);
        }

        $contents->addBr();
        $contents->addPre(print_r($this->fields, TRUE));
        $container = $contents->encapsulate('div', 'container');
        $body = $container->encapsulate('body');

        return $body;
    }

    /**
     * Viewing the entire element.
     *
     * @return string
     */
    public function view() {

        /**
         * XML declaration.
         */
        $output = '<?xml version="1.0" encoding="' . CHARSET . '" ?>' . "\n";

        /**
         * Normal viewing.
         */
        $output .= parent::view();

        /**
         * Final text string.
         */
        return $output;
    }

}